import org.omg.PortableInterceptor.INACTIVE;

import java.awt.*;
import java.io.ObjectOutputStream;
import java.util.*;
import java.util.List;

//二维数组最长增长序列长度
public class Main {

    private static int max = Integer.MIN_VALUE;

    public static void main(String[] args) {
        int[][] matrix = {
                {2, 5, 3, 0},
                {100, 4, 7, 5},
                {166, 9, 8, 3},
                {1, 2, 4, 5}
        };
        System.out.println(get2(matrix));
    }

    public static int get(int[][] matrix, int x, int y) {
        if (x < 0 || x >= matrix.length || y < 0 || y >= matrix[0].length) {
            return 0;
        }
        int path = 1;
        if (y > 0 && matrix[x][y] < matrix[x][y - 1]) {
            path = get(matrix, x, y - 1) + 1;
        }
        if (x > 0 && matrix[x][y] < matrix[x - 1][y]) {
            path = Math.max(path, get(matrix, x - 1, y) + 1);
        }
        if (y < matrix[0].length - 1 && matrix[x][y] < matrix[x][y + 1]) {
            path = Math.max(path, get(matrix, x, y + 1) + 1);
        }
        if (x < matrix.length - 1 && matrix[x][y] < matrix[x + 1][y]) {
            path = Math.max(path, get(matrix, x + 1, y) + 1);
        }
        return path;
    }

    public static int get2(int[][] matrix) {
        int[][] dp = new int[matrix.length][matrix[0].length];
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++) {
                max = Math.max(max, helper(matrix, dp, i - 1, j, matrix[i][j]) + 1);
                max = Math.max(max, helper(matrix, dp, i, j - 1, matrix[i][j]) + 1);
                max = Math.max(max, helper(matrix, dp, i + 1, j, matrix[i][j]) + 1);
                max = Math.max(max, helper(matrix, dp, i, j + 1, matrix[i][j]) + 1);
            }
        }
        return max;
    }

    public static int helper(int[][] matrix, int[][] dp, int x, int y, int n) {
        if (x < 0 || x >= matrix.length || y < 0 || y >= matrix[0].length || matrix[x][y] <= n) {
            return 0;
        }
        if (dp[x][y] == 0) {
            dp[x][y] = helper(matrix, dp, x - 1, y, matrix[x][y]) + 1;
            dp[x][y] = Math.max(helper(matrix, dp, x, y - 1, matrix[x][y]) + 1, dp[x][y]);
            dp[x][y] = Math.max(helper(matrix, dp, x + 1, y, matrix[x][y]) + 1, dp[x][y]);
            dp[x][y] = Math.max(helper(matrix, dp, x, y + 1, matrix[x][y]) + 1, dp[x][y]);
        }
        return dp[x][y];
    }
}
